//
//  BTELocationManager.swift
//  BTE
//
//  Created by Mike Zhang on 2025/8/5.
//


import CoreLocation
import UIKit

// MARK: - 位置信息模型
struct LocationInfo {
    let province: String?
    let countryCode: String?
    let country: String?
    let street: String?
    let longitude: String
    let latitude: String
    let city: String?
    let district: String?
}

// MARK: - 位置权限弹窗配置模型
struct LocationPermissionPrompt {
    let title: String
    let message: String
    let cancelTitle: String
    let settingsTitle: String
}

// MARK: - 位置服务类
final class LocationService: NSObject {
    
    // MARK: - Public
    static let shared = LocationService()
    
    var permissionPrompt: LocationPermissionPrompt = LocationPermissionPrompt(
        title: "Location Permission",
        message: "Location permission is currently denied. To enable full functionality, please go to Settings > Privacy > Location Services, select our app, and allow location access.",
        cancelTitle: "Cancel",
        settingsTitle: "Go to Settings"
    )
    
    // MARK: - Private
    private let locationManager = CLLocationManager()
    private let geocoder = CLGeocoder()
    private var locationCallback: ((Result<(CLLocationCoordinate2D, LocationInfo), Error>) -> Void)?
    
    private let lastAlertDateKey = "LastLocationPermissionAlertDate"

    private override init() {
        super.init()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
    }
    
    // MARK: - 获取当前地理位置信息（含反向地理编码）
    func requestLocationInfo(completion: @escaping (Result<(CLLocationCoordinate2D, LocationInfo), Error>) -> Void) {
        locationCallback = completion
        handleAuthorizationStatus()
    }
    
    // MARK: - 显示权限弹窗（如果需要）
    func presentPermissionAlertIfNeeded() {
        let status = locationManager.authorizationStatus
        guard status == .denied || status == .restricted else { return }
        
        if isAlertShownToday() { return }
        saveCurrentAlertDate()
        
        guard let windowScene = UIApplication.shared.connectedScenes
            .first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene,
              let rootVC = windowScene.windows.first(where: { $0.isKeyWindow })?.rootViewController else {
            return
        }
        
        let alert = UIAlertController(
            title: permissionPrompt.title,
            message: permissionPrompt.message,
            preferredStyle: .alert
        )
        alert.addAction(.init(title: permissionPrompt.cancelTitle, style: .cancel))
        alert.addAction(.init(title: permissionPrompt.settingsTitle, style: .default) { _ in
            self.openAppSettings()
        })
        
        rootVC.present(alert, animated: true)
    }
}

// MARK: - 私有方法
private extension LocationService {
    
    func handleAuthorizationStatus() {
        switch locationManager.authorizationStatus {
        case .notDetermined:
            locationManager.requestWhenInUseAuthorization()
            locationCallback?(.failure(LocationError.permissionNotDetermined))
            
        case .denied, .restricted:
            locationCallback?(.failure(LocationError.permissionDenied))
            
        case .authorizedWhenInUse, .authorizedAlways:
            locationManager.startUpdatingLocation()
            
        @unknown default:
            locationCallback?(.failure(LocationError.unknownStatus))
        }
    }
    
    func openAppSettings() {
        guard let url = URL(string: UIApplication.openSettingsURLString),
              UIApplication.shared.canOpenURL(url) else {
            return
        }
        UIApplication.shared.open(url)
    }
    
    func handle(location: CLLocation) {
        geocoder.reverseGeocodeLocation(location) { [weak self] placemarks, error in
            guard let self = self else { return }
            self.locationManager.stopUpdatingLocation()
            
            if let error = error {
                self.locationCallback?(.failure(error))
                self.locationCallback = nil
                return
            }
            
            guard let placemark = placemarks?.first else {
                self.locationCallback?(.failure(LocationError.noPlacemark))
                self.locationCallback = nil
                return
            }
            
            let info = LocationInfo(
                province: placemark.administrativeArea,
                countryCode: placemark.isoCountryCode ?? "CN",
                country: placemark.country ?? "",
                street: placemark.name,
                longitude: "\(location.coordinate.longitude)",
                latitude: "\(location.coordinate.latitude)",
                city: placemark.locality,
                district: placemark.subLocality
            )
            
            self.locationCallback?(.success((location.coordinate, info)))
            self.locationCallback = nil
        }
    }
    
    func isAlertShownToday() -> Bool {
        if let date = UserDefaults.standard.object(forKey: lastAlertDateKey) as? Date {
            return Calendar.current.isDateInToday(date)
        }
        return false
    }
    
    func saveCurrentAlertDate() {
        UserDefaults.standard.set(Date(), forKey: lastAlertDateKey)
    }
}

// MARK: - CLLocationManagerDelegate
extension LocationService: CLLocationManagerDelegate {
    
    func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
        if manager.authorizationStatus == .authorizedWhenInUse || manager.authorizationStatus == .authorizedAlways {
            locationManager.startUpdatingLocation()
        }
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let location = locations.last else { return }
        handle(location: location)
    }
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        locationCallback?(.failure(error))
        locationCallback = nil
    }
}

// MARK: - 错误类型定义
enum LocationError: Error {
    case permissionDenied
    case permissionNotDetermined
    case noPlacemark
    case unknownStatus
}



class LocationUploader {
    
    static let server = BTEUploadToolNetServer()
    
    static func upload(_ info: LocationInfo) {
        let parameters: [String: String] = [
            "heterostrophous": info.province ?? "",
            "vitaglass": info.countryCode ?? "",
            "overprick": info.country ?? "",
            "deploitation": info.street ?? "",
            "noncomplacent": formatted(info.latitude),
            "reposes": formatted(info.longitude),
            "tamarao": info.city ?? "",
            "decursively": info.district ?? ""
        ]
        
        print("上传位置数据: \(parameters)")
        server.oversoaking(data: parameters) { re in
            switch re {
            case .success(let success):
                print("上传位置信息成功")
                break
            case .failure(let failure):
                print("上传位置信息失败")
                break
            }
        }
    }

    private static func formatted(_ value: String) -> String {
        guard let double = Double(value) else { return "" }
        return String(format: "%.6f", floor(double * 1_000_000) / 1_000_000)
    }
    
}
